package com.songcha.library_common.ui.view

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Point
import android.graphics.PointF
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import com.songcha.library_common.R
import com.songcha.library_common.util.BitmapUtil
import com.songcha.library_common.util.LogUtil
import com.songcha.library_common.util.ScreenUtil
import com.songcha.library_common.util.ToastUtil
import com.songcha.library_common.util.dp2px
import com.songcha.library_common.util.sp2px
import kotlin.math.absoluteValue


class LineChatView
@JvmOverloads
constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0,
    defRes: Int = 0
) : View(context,attrs,defStyle,defRes) {

    private var mPoints = mutableListOf<Int>()
    private var mPerPointHeight=10f.dp2px()
    private var mLineColor=Color.GREEN
    private var mLineWidth=2f.dp2px()
    private var mPointColor=Color.GREEN
    private var mPointRadius=5f.dp2px()
    private var mItemWidth=50f.dp2px()

    private lateinit var mLinePaint:Paint
    private lateinit var mPointPaint:Paint

    private var mLastX = 0f
    private var mTouchX = 0f
    private var mScrollX = 0f
    private var mScaledTouchSlop = 0
    private var mMaxScrollX = 0f

    val mDrawPoints= mutableListOf<PointF>()

    private lateinit var mPath: Path

    init {
        initView(context, attrs)
    }

    private fun initView(context: Context, attrs: AttributeSet?){
        isClickable = true

        mScaledTouchSlop = ViewConfiguration.get(context).scaledTouchSlop

        if(attrs!=null){
            val ta=context.obtainStyledAttributes(attrs, R.styleable.LineChatView)
            mPerPointHeight=ta.getDimension(R.styleable.LineChatView_linechat_per_point_height,10f.dp2px())
            mLineColor=ta.getColor(R.styleable.LineChatView_linechat_line_color,Color.GREEN)
            mLineWidth=ta.getDimension(R.styleable.LineChatView_linechat_line_width,2f.dp2px())
            mPointColor=ta.getColor(R.styleable.LineChatView_linechat_point_color,Color.GREEN)
            mPointRadius=ta.getDimension(R.styleable.LineChatView_linechat_point_radius,5f.dp2px())
            mItemWidth=ta.getDimension(R.styleable.LineChatView_linechat_item_width,50f.dp2px())
            ta.recycle()
        }

        mLinePaint=Paint()
        mLinePaint.isAntiAlias=true
        mLinePaint.color=mLineColor
        mLinePaint.strokeWidth=mLineWidth
        mLinePaint.style=Paint.Style.STROKE

        mPointPaint=Paint()
        mPointPaint.isAntiAlias=true
        mPointPaint.color=mPointColor
        mPointPaint.strokeWidth=mLineWidth
        mPointPaint.style=Paint.Style.FILL
    }


    fun setPoints(points:MutableList<Int>){
        mPoints=points
        requestLayout()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val widthMode=MeasureSpec.getMode(widthMeasureSpec)
        val heightMode=MeasureSpec.getMode(heightMeasureSpec)
        if(widthMode!=MeasureSpec.EXACTLY && heightMode!=MeasureSpec.EXACTLY){
            if(mPoints.size==0) return
            val max=mPoints.max()
            val min=mPoints.min()
            val diff=max-min
            val h=(diff+1)*mPerPointHeight
            mMaxScrollX = (mItemWidth*mPoints.size)-ScreenUtil.getScreenWidth()
            setMeasuredDimension((mItemWidth*mPoints.size).toInt(),h.toInt())
        }

    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        mPath=Path()
        mDrawPoints.clear()
        if(mPoints.size==0) return
        for(i in 0 until mPoints.size){
            val diff=mPoints[i]-mPoints.min()
            val cx=((measuredWidth/mPoints.size)*i+(measuredWidth/mPoints.size)/2).toFloat()
            val cy=(measuredHeight-diff*mPerPointHeight-mPerPointHeight/2)
            mDrawPoints.add(PointF(cx,cy))
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when(event.action){
            MotionEvent.ACTION_DOWN->{
                mLastX = event.x
                mTouchX = event.x
            }
            MotionEvent.ACTION_MOVE->{
                mScrollX += (event.x - mTouchX)
                mTouchX = event.x
                if((mScrollX).absoluteValue>mScaledTouchSlop){
                    if(mScrollX>0f) mScrollX = 0f
                    if(mScrollX<mMaxScrollX*-1f) mScrollX = mMaxScrollX*-1f
                    invalidate()
                    return true
                }
            }
            MotionEvent.ACTION_UP->{

            }
            MotionEvent.ACTION_CANCEL->{

            }
        }

        return super.onTouchEvent(event)

    }

    fun scrollToX(scrollX:Float){
        if(scrollX>0 || scrollX<mMaxScrollX*-1) return
        mScrollX = scrollX
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        if(mDrawPoints.size==0) return

        canvas.save()

        canvas.translate(mScrollX,0f)

        mPath.reset()
        for(i in 0 until mDrawPoints.size){
            if(i==0)
                mPath.moveTo(mDrawPoints[i].x,mDrawPoints[i].y)
            else
                mPath.lineTo(mDrawPoints[i].x,mDrawPoints[i].y)
        }
        canvas.drawPath(mPath,mLinePaint)

        for(i in 0 until mDrawPoints.size){
            canvas.drawCircle(mDrawPoints[i].x,mDrawPoints[i].y,mPointRadius,mPointPaint)
        }

        canvas.restore()

    }


}